/*
 * detect_cl_types.h
 *
 *  Created on: 2016年6月19日
 *      Author: guyadong
 */

#ifndef FACEDETECT_DETECT_CL_TYPES_H_
#define FACEDETECT_DETECT_CL_TYPES_H_
#include <cstdint>
#include <vector>
namespace gdface{
/*
 * 通用整数2维向量定义，比如：用于定义坐标/尺寸
 */
typedef union _gf_int2{
	struct {int32_t x,y;};
	struct {int32_t w,h;};
	struct {int32_t s0,s1;};
}gf_int2;
/*
* 通用浮点数2维向量定义，比如：用于归一化坐标/尺寸定义
*/
typedef union _gf_float2 {
	struct { float x, y; };
	struct { float w, h; };
	struct { float s0,s1;};
}gf_float2;

/*
 * 默认矩形定义
 */
typedef union _gf_rect_def{
	struct {int32_t left,top,width,height;};
	struct {int32_t x,y,w,h;};
	struct {int32_t x1,y1,x2,y2;};
	struct {gf_int2 lt,rb;};
}gf_rect_def;
/*
 * 归一化矩形定义
 */
typedef union _gf_rect_norm{
	struct { float left, top, width, height; };
	struct { float x, y, w, h; };
	struct { float x1,y1,x2,y2; };
	struct { gf_float2 lt, rb; };
}gf_rect_norm;
/*
 * 归一化和默认矩形定义组成的联合体
 */
typedef union _obj_rect{
	gf_rect_norm norm;
	gf_rect_def def;
}gf_rect;
typedef std::vector<gf_rect> object_info_vector;
/*
 * 将归一化坐标根据提供的图像尺寸(img_size)转为默认坐标
 */
inline gf_rect_def gf_rect_unnormalization(const gf_rect_norm& norm_obj, const gf_int2& img_size) {
	gf_rect_def obj;
	obj.x = (int32_t) ((norm_obj.x * img_size.x));
	obj.y = (int32_t) ((norm_obj.y * img_size.y));
	obj.w = (int32_t) ((norm_obj.w * img_size.x));
	obj.h = (int32_t) ((norm_obj.h * img_size.y));
	return obj;
}
/*
 * 将归一化坐标根据提供的图像尺寸(img_size)转为默认坐标
 */
inline object_info_vector& convert_def(object_info_vector& objects, const gf_int2& img_size) {
	for (size_t i = 0; i < objects.size(); ++i) {
		objects[i].def = gf_rect_unnormalization(objects[i].norm, img_size);
	}
	return objects;
}

/*
 * 将归一化坐标根据提供的图像尺寸(img_size)转为默认坐标
 */
inline object_info_vector convert_def(const object_info_vector& objects, const gf_int2& img_size) {
	object_info_vector ret(objects);
	return convert_def(ret, img_size);
}
/*
 * 图像色彩空间定义,顺序与 jpeglib.h定义相同
 *  */
typedef enum {
	GFCS_UNKNOWN,            /* error/unspecified */
	GFCS_GRAYSCALE,          /* monochrome */
	GFCS_RGB,                /* red/green/blue as specified by the RGB_RED,
	                           RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros */
	GFCS_YCbCr,              /* Y/Cb/Cr (also known as YUV) */
	GFCS_CMYK,               /* C/M/Y/K */
	GFCS_YCCK,               /* Y/Cb/Cr/K */
	GFCS_EXT_RGB,            /* red/green/blue */
	GFCS_EXT_RGBX,           /* red/green/blue/x */
	GFCS_EXT_BGR,            /* blue/green/red */
	GFCS_EXT_BGRX,           /* blue/green/red/x */
	GFCS_EXT_XBGR,           /* x/blue/green/red */
	GFCS_EXT_XRGB,           /* x/red/green/blue */
	/* When out_color_space it set to GFCS_EXT_RGBX, GFCS_EXT_BGRX, GFCS_EXT_XBGR,
	   or GFCS_EXT_XRGB during decompression, the X byte is undefined, and in
	   order to ensure the best performance, libjpeg-turbo can set that byte to
	   whatever value it wishes.  Use the following colorspace constants to
	   ensure that the X byte is set to 0xFF, so that it can be interpreted as an
	   opaque alpha channel. */
	GFCS_EXT_RGBA,           /* red/green/blue/alpha */
	GFCS_EXT_BGRA,           /* blue/green/red/alpha */
	GFCS_EXT_ABGR,           /* alpha/blue/green/red */
	GFCS_EXT_ARGB,           /* alpha/red/green/blue */
	GFCS_RGB565              /* 5-bit red/6-bit green/5-bit blue */
} Gf_COLOR_SPACE;
/* 图像矩阵基本参数 */
typedef struct _image_matrix_base{
	uint32_t		width;		// 图像宽度
	uint32_t		height;		// 图像高度
	uint8_t			channels;	// 通道数
	Gf_COLOR_SPACE	color_space;// 图像数据的色彩空间
	uint8_t			align;		// 内存对齐方式 0为不对齐，>0为以2的n次幂对齐
}image_matrix_base,*image_matrix_base_ptr;

/*
 * 图像矩阵参数
 * 图像数据保存在pixels指向的内存中
 * 图像数据长度由image_matrix_base中各参数定义,
 * 参见 get_image_matrix_size函数
 *  */
typedef struct _image_matrix:image_matrix_base{
	uint8_t*		pixels; 	// 图像数据指针
}image_matrix,*image_matrix_ptr;
/* 图像矩阵参数
 * 图像数据保存在std::vector对象
 * std::vector对象的内存大小必须与image_matrix_base中各参数定义的值,相等
 * 参见 get_image_matrix_size函数
 * */
typedef struct _image_matrix_v:image_matrix_base{
	std::vector<uint8_t>		pixels; // 图像数据
}image_matrix_v,*image_matrix__vptr;
/*
* 获取矩阵行对齐宽度(像素)
* */
inline uint32_t get_row_stride(const image_matrix_base&matrix) {
	// align只取低4位
	uint32_t m = (1U << (matrix.align & 0x0f)) - 1;
	return uint32_t((matrix.width+m)&(~m));
}
/*
* 获取矩阵内存大小(字节)
* */
inline uint32_t get_image_matrix_size(const image_matrix_base&matrix) {
	return uint32_t(get_row_stride(matrix)*matrix.height*matrix.channels);
}
/*
 * image_matrix_v转换为image_matrix
 * 注意：
 * 这里image_matrix对pixels指针没有分配内存,
 * 只是共享了输入参数对象(src)的vector成员变量的内存
 * 所以返回的image_matrix对象不能脱离src对象的生命周期而存在
 * 所以在C++11下,src不能为右值引用
 * */
inline image_matrix to_image_matrix(const image_matrix_v& src){
	image_matrix dst;
	*(image_matrix_base *)(&dst)=*(const image_matrix_base *)(&src);
	dst.pixels=(uint8_t*)src.pixels.data();
	return dst;
}
}/*namespace gdface*/


#endif /* FACEDETECT_DETECT_CL_TYPES_H_ */
